package cn.sciento.message.infra.supporter;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import cn.sciento.boot.message.entity.DingTalkSender;
import cn.sciento.dd.dto.MarkDownFormat;
import cn.sciento.dd.dto.SendWorkMarkDownMessageDTO;
import cn.sciento.dd.dto.SendWorkMessageResultDTO;
import cn.sciento.dd.service.DingCorpMessageService;
import cn.sciento.message.domain.entity.Message;
import cn.sciento.message.infra.exception.SendMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.sciento.core.convertor.ApplicationContextHelper;
import cn.sciento.core.exception.CommonException;


/**
 * 钉钉消息
 *

 */
public class DingTalkServerSupporter {

    private static final Logger logger = LoggerFactory.getLogger(DingTalkServerSupporter.class);
    private static final ObjectMapper OBJECT_MAPPER = ApplicationContextHelper.getContext().getBean(ObjectMapper.class);
    private static final String MARKDOWN_MESSAGE = "markdown";

    private DingTalkServerSupporter() {
    }


    private static SendWorkMarkDownMessageDTO generateMessage(List<String> userList, Message message) {
        SendWorkMarkDownMessageDTO markdownMessage = new SendWorkMarkDownMessageDTO();
        try {
            markdownMessage.setUserid_list(buildParam(userList));
            Map<String, String> map =
                    OBJECT_MAPPER.readValue(message.getSendArgs(), new TypeReference<Map<String, String>>() {
                    });
            String agentStr = map.get(DingTalkSender.FIELD_AGENT_ID);
            markdownMessage.setAgent_id(Objects.equals(agentStr, "null") ? 0L : Long.parseLong(agentStr));
            if (map.containsKey(DingTalkSender.FIELD_DEPT_ID_LIST)) {
                markdownMessage.setDept_id_list(buildParam(OBJECT_MAPPER.readValue(
                        map.get(DingTalkSender.FIELD_DEPT_ID_LIST), new TypeReference<List<String>>() {
                        })));
            }
            if (map.containsKey(DingTalkSender.FIELD_TO_ALL_USER)) {
                markdownMessage.setTo_all_user(OBJECT_MAPPER.readValue(map.get(DingTalkSender.FIELD_TO_ALL_USER),
                        new TypeReference<Boolean>() {
                        }));
            }
            MarkDownFormat msg = new MarkDownFormat();
            MarkDownFormat.MarkdownBean markdown = new MarkDownFormat.MarkdownBean();
            markdown.setTitle(message.getSubject());
            markdown.setText(String.format("## %s%n,%s", message.getSubject(), message.getContent().replaceAll("<[.[^<]]*>", "")));
            msg.setMsgtype(MARKDOWN_MESSAGE);
            msg.setMarkdown(markdown);
            markdownMessage.setMsg(msg);
            return markdownMessage;
        } catch (IOException e) {
            logger.error("Incorrect parameter format");
            throw new CommonException(e);
        }
    }

    private static String buildParam(List<String> list) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        list.forEach(item -> sb.append(item).append(","));
        return sb.toString().endsWith(",") ? sb.toString().substring(0, sb.length() - 1) : null;
    }

    /**
     * 发送钉钉模板消息
     */
    public static void sendMessage(DingCorpMessageService messageService, String token, List<String> userList,
                                   Message message) {
        SendWorkMarkDownMessageDTO workMessage = generateMessage(userList, message);
        SendWorkMessageResultDTO response = messageService.sendWorkMarkDownMessage(token, workMessage);
        if (response.getErrcode() != 0) {
            throw new SendMessageException(String.format("dingtalk message send failed! code: [%s] , message: [%s]",
                    response.getErrcode(), response.getErrmsg()));
        }
    }


}
